<script lang="tsx">
import useRender from "@/utils/hooks/render";
import {
  computed,
  defineComponent,
  inject,
  reactive,
  useCssModule,
  toRefs,
  watch,
  toRaw,
} from "vue";
import FormListVue from "./fields/form-list-field.vue";
import TextField from "./fields/text-field.vue";
import TextAreaField from "./fields/textarea-field.vue";
import SelectField from "./fields/select-field/index.vue";
import FileField from "./fields/file-field.vue";
import DateField from "./fields/date-field.vue";
import TimeField from "./fields/time-field/index.vue";
import { Column, NormalItem } from "./index.vue";
import { objByPath, useCurrPathRef } from "./utils";
import { CustomWrapper } from "@tarojs/components";

const FieldItem = defineComponent({
  name: "field-item",
  props: {
    item: {
      type: Object as () => Column,
      required: true,
    },
    parentPath: {
      type: String,
    },
  },
  setup(props, ctx) {
    const style = useCssModule();

    const currPath = useCurrPathRef(props.item, props.parentPath);
    const changeValue =
      inject<(path: string, value: any) => void>("changeValue");
    const rootModal = inject<Record<string, any>>("rootModal")!;

    const fieldValue = computed(() =>
      objByPath(rootModal, currPath.value).get()
    );

    const baseProps = computed(() => ({
      ...(props.item.fieldProps || {}),
      // 必须有的两个字段
      fieldValue: fieldValue.value,
      // 赋值操作不写在computed中
      // onFieldChange: (e) => changeValue?.(currPath.value, e),
    }));

    const FieldComp = computed(() => {
      return {
        text: <TextField {...baseProps.value}></TextField>,
        textarea: <TextAreaField {...baseProps.value}></TextAreaField>,
        select: (
          <SelectField
            {...baseProps.value}
            remote={props.item.remote}
            columns={props.item.options}
          ></SelectField>
        ),
        file: <FileField {...baseProps.value}></FileField>,
        date: <DateField {...baseProps.value}></DateField>,
        time: <TimeField {...baseProps.value}></TimeField>,
      }[props.item.valueType || "text"];
    });

    const renderArgs = computed<
      Parameters<NonNullable<NormalItem["render"]>>[0]
    >(() => {
      if (props.item.render) {
        return {
          modal: rootModal,
          currPath: currPath.value,
          // item: props.item,
        };
      }
      return { modal: {}, currPath: "" };
    });

    useRender(() => {
      if (props.item.valueType === "group") {
        return (
          <div class="group">
            <div class="">{props.item.title}</div>
            {props.item.columns.map((el) => {
              return <FieldItem item={el}></FieldItem>;
            })}
          </div>
        );
      } else if (props.item.valueType === "formList") {
        return <FormListVue item={props.item}></FormListVue>;
      } else {
        return (
          <nut-form-item
            class={style["write-color"]}
            label={props.item.title}
            prop={currPath.value}
            rules={props.item.rules}
            {...(props.item.formItemProps || {})}
          >
            {props.item.render ? (
              props.item.render(renderArgs.value)
            ) : (
              <FieldComp.value
                onFieldChange={(e) => changeValue?.(currPath.value, e)}
              />
            )}
          </nut-form-item>
        );
      }
    });

    return {
      currPath,
      rootModal,
      baseProps,
      fieldValue,
    };
  },
});

export default FieldItem;
</script>

<style lang="scss" module>
.write-color :global .nut-form-item__body__slots {
  color: var(--nut-textarea-text-color, var(--nut-title-color, #1a1a1a));
}
</style>
